package com.tencent.wxpay.business;

import com.tencent.wxpay.businessListener.BaseResultListener;
import com.tencent.wxpay.common.Configure;
import com.tencent.wxpay.common.Signature;
import com.tencent.wxpay.common.Util;
import com.tencent.wxpay.common.XMLParser;
import com.tencent.wxpay.common.report.ReporterFactory;
import com.tencent.wxpay.common.report.protocol.ReportReqData;
import com.tencent.wxpay.common.report.service.ReportService;
import com.tencent.wxpay.protocol.request.RefundReqData;
import com.tencent.wxpay.protocol.response.PayResultResData;
import com.tencent.wxpay.protocol.response.RefundResData;
import com.tencent.wxpay.service.RefundService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * 支付回调服务
 */
public class PayResultBusiness {

    private static final Logger logger = LoggerFactory.getLogger(PayResultBusiness.class);

    /**
     * 运行支付回调服务
     * @param payResultResponseString 支付异步回调返回的数据流
     * @param resultListener 业务逻辑可能走到的结果分支，需要商户处理
     * @return RefundResData 返回的数据对象
     * @throws Exception
     */
    public static void run(String payResultResponseString, BaseResultListener<PayResultResData> resultListener) throws Exception {
        PayResultResData payResultResData = (PayResultResData)Util.getObjectFromXML(payResultResponseString,PayResultResData.class);
        String outTradeNo = payResultResData.getOut_trade_no();
        // API通信失败
        if (payResultResData == null || payResultResData.getReturn_code() == null) {
            logger.error("【支付失败】【订单号："+outTradeNo+"】支付回调逻辑错误，请仔细检测传过去的每一个参数是否合法，或是看API能否被正常访问");
            resultListener.onFailByReturnCodeError(payResultResData);
            return;
        }
        // API通信成功，但调用出错，可能签名失败或参数格式校验错误
        if (payResultResData.getReturn_code().equals("FAIL")) {
            ///注意：一般这里返回FAIL是出现系统级参数错误，请检测Post给API的数据是否规范合法
            logger.error("【支付失败】【订单号："+outTradeNo+"】支付回调接口系统返回失败，请检测Post给API的数据是否规范合法");
            resultListener.onFailByReturnCodeFail(payResultResData);
            return;
        } else {
            // API通信成功，调用接口成功，有返回数据,但业务不一定执行成功
            logger.info("支付回调接口【订单号："+outTradeNo+"】成功返回数据");
            //--------------------------------------------------------------------
            //收到API的返回数据的时候得先验证一下数据有没有被第三方篡改，确保安全
            //--------------------------------------------------------------------
            if (!Signature.checkIsSignValidFromResponseString(payResultResponseString)) {
                logger.error("【支付失败】【订单号："+outTradeNo+"】支付回调API返回的数据签名验证失败，有可能数据被篡改了");
                resultListener.onFailBySignInvalid(payResultResData);
                return;
            }

            if (payResultResData.getResult_code().equals("FAIL")) {
                logger.error("【支付失败】【订单号："+outTradeNo+"】");
                logger.error("错误码：" + payResultResData.getErr_code());
                logger.error("错误信息：" + payResultResData.getErr_code_des());
                //退款失败时再怎么延时查询退款状态都没有意义，这个时间建议要么再手动重试一次，依然失败的话请走投诉渠道进行投诉
                resultListener.onFail(payResultResData);
            } else {
                //退款成功
                logger.info("【支付成功】【订单号："+outTradeNo+"】");
                resultListener.onSuccess(payResultResData);
            }
        }
    }
}
